#define _CRT_SECURE_NO_WARNINGS

#include "printer_console.h"

#include <iostream>
using namespace std;

#define SPACE ::testing::internal

PrinterConsole::PrinterConsole()
    :mSUCCEED(false)
{}

void PrinterConsole::OnTestProgramStart(const UnitTest& /* unit_test */) 
{
    ColoredPrintf( SPACE::COLOR_GREEN, "[ Run the test program ]");
    cout<<endl;
}

void PrinterConsole::OnTestStart(const TestInfo& test_info) 
{
    ColoredPrintf( SPACE::COLOR_GREEN, "[ Test starting ] ");
    ColoredPrintf( SPACE::COLOR_YELLOW, "");
    mNameTest =test_info.test_case_name();
    mNameTest +=".";
    mNameTest +=test_info.name();
    cout<< mNameTest<<endl;
}

void PrinterConsole::OnTestPartResult(const TestPartResult& test_part_result) 
{
    if(!test_part_result.failed()) 
    {  
        ColoredPrintf( SPACE::COLOR_GREEN, "SUCCEED");
        mSUCCEED=true; 
        cout<<endl;
        return;    
    }
    if(mNameBugs.size()>0 && mNameBugs.back()==mNameTest) 
        cout<< '\n'<< Str(23 + mNameTest.size(), ' ');

    ColoredPrintf( SPACE::COLOR_RED, "FAILED ");
    mNameBugs.push_back(mNameTest);

    std::stringstream msg;

    msg << test_part_result.summary();
    msg << test_part_result.line_number();
    mBugsReport.push_back( msg.str() );
    return;  
}

void PrinterConsole::OnTestEnd(const TestInfo& test_info) 
{
    if(mSUCCEED==true) 
        return mSUCCEED = false, void();
    
    if (test_info.result()->Passed()) 
        ColoredPrintf( SPACE::COLOR_GREEN, "OK"); 
    cout<<endl;
}

void PrinterConsole::OnTestProgramEnd(const UnitTest& unit_test) 
{
    for(size_t n=0; n<mBugsReport.size();++n)
    {
        PrintSystem("\n  TEST FAILED  ",SPACE::COLOR_RED);
        fprintf(stdout, "%s.....", mNameBugs[n].c_str());
        ColoredPrintf( SPACE::COLOR_RED, "FAILED"); 
        fprintf(stdout, "\n%s\n", mBugsReport[n].c_str());
    }
    
//     size_t nRun        = unit_test.test_to_run_count();
//     size_t nTotalCase  = unit_test.total_test_case_count();
    size_t nTotalTest  = unit_test.total_test_count();
//    size_t nSuccesCase = unit_test.successful_test_case_count();
    size_t nSuccesTest = unit_test.successful_test_count();
    size_t nDisabled = unit_test.disabled_test_count();
    size_t nFailed = nTotalTest-nSuccesTest- nDisabled;

//     (void) nTotalCase;
//     (void) nSuccesCase;
//     (void) nRun;
    
    fprintf(stdout, "\n");
    PrintTotal("TotalTest.....", nTotalTest);  fprintf(stdout, "\n");
    PrintTotal("SuccessTest...", nSuccesTest); fprintf(stdout, "\n");
    
    if(nDisabled>0) { PrintTotal("DisabledTest..", nDisabled,SPACE::COLOR_RED); fprintf(stdout, "\n"); }
    if(nFailed==0)  { PrintTotal("FailedTest....", nFailed,SPACE::COLOR_GREEN); }
    else            { PrintTotal("FailedTest....", nFailed,SPACE::COLOR_RED);   }

    fprintf(stdout, "\n");
    PrintResult(unit_test);
    cout<<endl;
}

void PrinterConsole::PrintTotal(const char* text, size_t val, SPACE::GTestColor col)const
{
    char line[256]; sprintf(line, "%d", val);
    
    ColoredPrintf( SPACE::COLOR_GREEN, "[ TOTAL ] ");
    ColoredPrintf( SPACE::COLOR_YELLOW, text); 
    ColoredPrintf( col, line);
}
void PrinterConsole::PrintResult(const UnitTest& unit_test)const
{
    if( unit_test.Passed() )  
        PrintSystem(" TOTAL ", SPACE::COLOR_GREEN),
        ColoredPrintf( SPACE::COLOR_GREEN, "TEST PASSED");
    else
        PrintSystem(" TOTAL ", SPACE::COLOR_RED),
        ColoredPrintf( SPACE::COLOR_RED, "TEST FAILED");

    fprintf(stdout, "\n");
}

void PrinterConsole::PrintSystem(const char* text, SPACE::GTestColor col)const
{
    ColoredPrintf( SPACE::COLOR_GREEN, "[");        
    ColoredPrintf( col, text);        
    ColoredPrintf( SPACE::COLOR_GREEN, "] ");        
}



